﻿Imports System.Collections.Specialized
Imports System.IO
Imports System.Globalization
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports System.Collections.ObjectModel
Imports System
Imports System.ComponentModel
Imports System.Xml.Serialization
Imports System.Threading
Imports Hinshelwood.TFSHeatITSM.TeamFoundationExtensions

Namespace Controlers

    Public Class TeamSystemControler(Of TView As {UIElement, ITeamSystemView(Of TView)})
        Inherits ControlerBase(Of TView)

        Public Sub New(ByVal View As TView)
            MyBase.New(View)
            Reset()
        End Sub

        Public Overrides Sub Reset()
            UpdateSelectedServer_Async(My.Settings.SelectedTeamServer)
        End Sub

#Region " Team Server "

        Private m_SelectedServer As TeamFoundationServer = Nothing
        Private Shared m_HasSelectedServer As Boolean = False

        Public Property SelectedServer() As TeamFoundationServer
            Get
                Return m_SelectedServer
            End Get
            Set(ByVal value As TeamFoundationServer)
                If m_SelectedServer Is Nothing OrElse Not value.Name = m_SelectedServer.Name Then
                    m_SelectedServer = value
                    My.Settings.SelectedTeamServer = value.Uri.ToString
                    'My.Settings.Save()
                    OnPropertyChanged("SelectedServer")
                    Application.Current.Dispatcher.BeginInvoke(New Action(Of TeamFoundationServer)(AddressOf View.TeamServerUpdated), SelectedServer)
                    'TeamSystemView.TeamServerUpdated(SelectedServer)
                    HasSelectedServer = True
                    UpdateWorkItemStore()
                    UpdateSelectedProject(My.Settings.SelectedTeamProject)
                End If
            End Set
        End Property

        Private Sub UpdateSelectedServer(ByVal TeamServer As TeamFoundationServer)
            TeamServer.EnsureAuthenticated()
            SelectedServer = TeamServer
        End Sub

        Private Sub UpdateSelectedServer(ByVal TeamServerName As String)
            Working = True
            Dim tfs As TeamFoundationServer
            tfs = View.GetTeamFoundationServer(TeamServerName)
            tfs.EnsureAuthenticated()
            SelectedServer = tfs
            Working = False
        End Sub

        Public Sub UpdateSelectedServer_Async(ByVal TeamServer As TeamFoundationServer)
            Dim action As New Action(Of TeamFoundationServer)(AddressOf UpdateSelectedServer)
            action.BeginInvoke(TeamServer, Nothing, Nothing)
        End Sub

        Public Sub UpdateSelectedServer_Async(ByVal TeamServerName As String)
            If Not String.IsNullOrEmpty(TeamServerName) Then
                Dim action As New Action(Of String)(AddressOf UpdateSelectedServer)
                action.BeginInvoke(TeamServerName, Nothing, Nothing)
            End If
        End Sub

        Public Property HasSelectedServer() As Boolean
            Get
                Return m_HasSelectedServer
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedServer Then
                    m_HasSelectedServer = value
                    OnPropertyChanged("HasSelectedServer")
                End If
            End Set
        End Property

        Private Shared m_WorkItemStore As WorkItemStore = Nothing

        Public Property WorkItemStore() As WorkItemStore
            Get
                Return m_WorkItemStore
            End Get
            Private Set(ByVal value As WorkItemStore)
                If Not value Is m_WorkItemStore Then
                    m_WorkItemStore = value
                    OnPropertyChanged("WorkItemStore")
                End If
            End Set
        End Property

        Private Sub UpdateWorkItemStore()
            If Not SelectedServer Is Nothing Then
                WorkItemStore = DirectCast(SelectedServer.GetService(GetType(WorkItemStore)), WorkItemStore)
            Else
                WorkItemStore = Nothing
            End If
        End Sub

        Public ReadOnly Property AvailableServers() As TeamFoundationServer()
            Get
                Return Microsoft.TeamFoundation.Client.RegisteredServers.GetServers
            End Get
        End Property

#End Region

#Region "Team Project"

        Private m_SelectedProject As Project = Nothing
        Private m_HasSelectedProject As Boolean = False

        Public Property SelectedProject() As Project
            Get
                Return m_SelectedProject
            End Get
            Set(ByVal value As Project)
                If m_SelectedProject Is Nothing OrElse Not value.Name = m_SelectedProject.Name Then
                    m_SelectedProject = value
                    If value Is Nothing Then
                        My.Settings.SelectedTeamProject = ""
                    Else
                        My.Settings.SelectedTeamProject = value.Name
                    End If
                    ' My.Settings.Save()
                    OnPropertyChanged("SelectedProject")
                    HasSelectedProject = Not m_SelectedProject Is Nothing
                End If
            End Set
        End Property

        Public Property HasSelectedProject() As Boolean
            Get
                Return m_HasSelectedProject
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedProject Then
                    m_HasSelectedProject = value
                    OnPropertyChanged("HasSelectedProject")
                End If
            End Set
        End Property

        Public Sub UpdateSelectedProject(ByVal ProjectName As String)
            If Not WorkItemStore.Projects.Contains(ProjectName) Then
                SelectedProject = Nothing
                Exit Sub
            End If
            SelectedProject = WorkItemStore.Projects(ProjectName)
        End Sub

#End Region

        Public Function GetWorkItemFromHeatCallLogID(ByVal id As Integer) As WorkItem
            Dim query As New System.Text.StringBuilder
            query.AppendFormat("SELECT [System.Id], [System.Title] FROM WorkItems WHERE [HeatITSM.Ref] = '{0}' ORDER BY [System.Id]", id)
            Try
                Dim wit As WorkItem = Nothing
                SyncLock WorkItemStore
                    Dim cx As WorkItemCollection = WorkItemStore.Query(query.ToString)
                    If Not cx Is Nothing AndAlso cx.Count > 0 Then
                        wit = WorkItemStore.GetWorkItem(cx(0).Id)
                    End If
                End SyncLock
                If Not wit Is Nothing Then
                    Return wit
                End If
            Catch ex As Exception
                Return Nothing
            End Try
            Return Nothing
        End Function

        Public ReadOnly Property HeatReferenceName() As String
            Get
                Return "HeatITSM.Ref"
            End Get
        End Property

        Public Function LoadWorkItem(ByVal witid As Integer) As WorkItem
            Return WorkItemStore.GetWorkItem(witid)
        End Function

        Public Function CheckServerField() As Boolean
            Dim v = (From fd As FieldDefinition In WorkItemStore.FieldDefinitions Where fd.ReferenceName = HeatReferenceName).SingleOrDefault
            Return Not (v Is Nothing)
        End Function

        Public Function CheckWorkItemField(ByVal wit As WorkItemType) As Boolean
            Dim v = (From fd As FieldDefinition In wit.FieldDefinitions Where fd.ReferenceName = HeatReferenceName).SingleOrDefault
            Return Not (v Is Nothing)
        End Function

        Public Function GetWorkItemField(ByVal wi As WorkItem, ByVal Reference As String) As Field
            Dim v = (From f As Field In wi.Fields Where f.ReferenceName = Reference).SingleOrDefault
            Return v
        End Function

    End Class

End Namespace